package sharewithus.business.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import framelib.dao.AbsDAO;

import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import sharewithus.business.dao.IRelationShipDAO;
import sharewithus.business.dto.RelationShipMsg;

/**
 * @ClassName: RelationShipDAOImpl
 * @Description:
 * @author chenyun
 * @date 2012-5-15 下午03:52:51
 */
public class RelationShipDAOImpl extends AbsDAO implements IRelationShipDAO {

	@Autowired
	@Qualifier("shardedJedisPool")
	private ShardedJedisPool jedisPool;

	@Autowired
	@Qualifier("jmsTemplate")
	private JmsTemplate jmsTemplate;

	private static String FANS_CACHE_PREFIX = "fans_";

	private static String FOLLOWER_CACHE_PREFIX = "follower_";

	public void addRelationShipInCache(String uid, String follower)
			throws Exception {

		ShardedJedis jedis = jedisPool.getResource();
		
		jedis.lpush(FOLLOWER_CACHE_PREFIX + uid, follower);
		jedis.lpush(FANS_CACHE_PREFIX + follower, uid);
	}

	public void removeRelationShipInCache(String uid, String follower)
			throws Exception {
		ShardedJedis jedis = jedisPool.getResource();
		jedis.lrem(uid, 1, follower);

		jedis.lrem(FOLLOWER_CACHE_PREFIX + uid, 1, follower);
		jedis.lrem(FANS_CACHE_PREFIX + follower, 1, uid);

	}

	public List<String> getFansFromCache(String uid) throws Exception {
		ShardedJedis jedis = jedisPool.getResource();

		long number = jedis.llen(FANS_CACHE_PREFIX + uid);

		List<String> fans = jedis.lrange(FANS_CACHE_PREFIX + uid, 0, number);

		return fans;
	}

	public List<String> getFansFromDB(String uid) throws Exception {
		Map<String, String> filter = new HashMap<String, String>();
		filter.put("user_id", uid);

		List<String> fans = this.getSqlMapClientTemplate().queryForList(
				"getFans", filter);
		return fans;
	}

	public List<String> getFansFromCache(String uid, long startIndex,
			long endIndex) throws Exception {
		ShardedJedis jedis = jedisPool.getResource();

		long number = jedis.llen(FANS_CACHE_PREFIX + uid);

		if (endIndex > number) {
			endIndex = number;
		}

		List<String> fans = jedis.lrange(FANS_CACHE_PREFIX + uid, startIndex,
				endIndex);

		return fans;
	}

	public List<String> getFollowersFromCache(String uid) throws Exception {
		ShardedJedis jedis = jedisPool.getResource();

		long number = jedis.llen(FANS_CACHE_PREFIX + uid);

		List<String> followers = jedis.lrange(FANS_CACHE_PREFIX + uid, 0,
				number);

		return followers;
	}

	public List<String> getFollowersFromDB(String uid) throws Exception {
		Map<String, String> filter = new HashMap<String, String>();
		filter.put("user_id", uid);

		List<String> fans = this.getSqlMapClientTemplate().queryForList(
				"getFollowers", filter);
		return fans;
	}

	public void putFans2Cache(String uid) throws Exception {
		List<String> fans = this.getFansFromDB(uid);

		ShardedJedis jedis = jedisPool.getResource();
		for (String fan : fans) {
			jedis.lpush(FANS_CACHE_PREFIX + uid, fan);
		}
	}

	public void putFollowers2Cache(String uid) throws Exception {
		List<String> followers = this.getFollowersFromDB(uid);

		ShardedJedis jedis = jedisPool.getResource();
		for (String follower : followers) {
			jedis.lpush(FOLLOWER_CACHE_PREFIX + uid, follower);
		}
	}

	public List<String> getFollowersFromCache(String uid, long startIndex,
			long endIndex) throws Exception {
		ShardedJedis jedis = jedisPool.getResource();

		long number = jedis.llen(FANS_CACHE_PREFIX + uid);

		if (endIndex > number) {
			endIndex = number;
		}

		List<String> followers = jedis.lrange(FOLLOWER_CACHE_PREFIX + uid,
				startIndex, endIndex);

		return followers;
	}

	public void putAddRSMsg2Queue(String uid, String follower) throws Exception {
		final RelationShipMsg msg = new RelationShipMsg();
		msg.setUserId(uid);
		msg.setFollower(follower);
		msg.setType("ADD");

		jmsTemplate.convertAndSend("rsQueue", msg);
	}

	public void putRemoveRSMsg2Queue(String uid, String follower)
			throws Exception {
		RelationShipMsg msg = new RelationShipMsg();
		msg.setUserId(uid);
		msg.setFollower(follower);
		msg.setType("CANCEL");

		jmsTemplate.convertAndSend("rsQueue", msg);
	}

	public long getFansNum(String uid) throws Exception {
		ShardedJedis jedis = jedisPool.getResource();

		return jedis.llen(FANS_CACHE_PREFIX + uid);
	}

	public long getFollowersNum(String uid) throws Exception {
		ShardedJedis jedis = jedisPool.getResource();

		return jedis.llen(FOLLOWER_CACHE_PREFIX + uid);
	}

}
